package collection.list;

import org.junit.Test;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;

public class c1_ArrayListNotSafeTest {

	/**
	 * 1.ArrayList 使用多线程修改list会报 java.util.ConcurrentModificationException
	 * <p>
	 * 2.使用Vector 多线程修改是线程安全的，add()方法上加了 synchronized
	 * <p>
	 * 3.Collections.synchronizedList(new ArrayList<>()); 多线程修改是线程安全的，该方法其实返回了
	 * new SynchronizedList<>(list))，该类对元素的操作方法，在方法中，加上了synchronized代码块
	 *
	 * @throws InterruptedException
	 */
	@Test
	public void test1() throws InterruptedException {
		//List<String> list = new ArrayList<>();
		//List<String> list = new Vector<>();
		List<String> list = Collections.synchronizedList(new ArrayList<>());

		for (int i = 0; i < 30; i++) {
			new Thread(() -> {
				String substring = UUID.randomUUID().toString().substring(0, 8);
				list.add(substring);
				System.out.println(substring + " - " + list);
			}, String.valueOf(i)).start();
		}
		TimeUnit.SECONDS.sleep(5);
	}

	/**
	 * 使用CopyOnWriteArrayList，多线程操作元素是线程安全的。CopyOnWriteArrayList是读写分离的。在新增元素add()
	 * 的时候，它会将原有的object[] A复制出一个object[] B，在B数组中操作元素，操作完成后，再将数组B指向远来的引用（array）
	 *
	 * @throws InterruptedException
	 */
	@Test
	public void test2() throws InterruptedException {
		List<String> list = new CopyOnWriteArrayList<>();

		for (int i = 0; i < 30; i++) {
			new Thread(() -> {
				String substring = UUID.randomUUID().toString().substring(0, 8);
				list.add(substring);
				System.out.println(substring + " - " + list);
				list.get(3);
			}, String.valueOf(i)).start();
		}
		TimeUnit.SECONDS.sleep(5);
	}
}
